package com.t.bricks.bussiness.service.recharge.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.t.bricks.bussiness.db.dao.recharge.RechargeDao;
import com.t.bricks.bussiness.db.entity.recharge.Recharge;
import com.t.bricks.bussiness.db.entity.recharge.base.WechatRefundBase;
import com.t.bricks.bussiness.service.recharge.RechargeService;
import com.t.bricks.bussiness.service.recharge.WeChatPayService;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.utils.function.data.MoneyUtil;
import com.t.bricks.utils.function.data.UUIDUtil;
import com.t.bricks.utils.spring.ModuleUtil;

/**
 * 微信方式充值服务 实现类
 * @author HuangXinBian
 */
@Service
public class WeChatPayServiceImpl implements WeChatPayService {
	
	/**
	 * 存储准备更新状态的充值号<充值号,状态>
	 */
	private static Map<String, Integer> mapState = new ConcurrentHashMap<>(5);
	
	@Autowired
	private RechargeDao rechargeDao;
	
	@Autowired
	private RechargeService rechargeService;

	/**
	 * 微信支付的IP白名单,同时设置在微信平台
	 */
	@Value("${app.wechat.white.ip:}")
	private String whiteIP;
	
	/**
	 * 创建sRecordKey用的干扰串
	 */
	@Value("${app.record.key.jam:123456}")
	private String recordKeyJam;
	
	/**
	 * 创建充值
	 * @param sOpenid 微信公开号
	 * @param mFund 充值金额
	 * @return
	 */
	@Override
	public MsgEmity createOrder(String sOpenid, BigDecimal mFund) {
		if (!MoneyUtil.isPlus(mFund)) {
			return MsgEmity.err(8001, "金额必须是正数！");
		}
//		MsgEmity me = rechargeDao.getRechargeTally(1, mFund.toString());
//		if (!me.isSuccess()) {
//			return me.appendDataCode(100);
//		}
		
		Integer iTally = mFund.setScale(0, BigDecimal.ROUND_DOWN ).intValue();//直接舍弃小数
		String sCustomerId = ModuleUtil.currentLoginUserId();
		String sOrderNo = UUIDUtil.get();
		String sBody = String.format("%s充值%s元", ModuleUtil.currentLoginUserName(), mFund.toString());
		Date now = new Date();
		
		Recharge recharge = new Recharge();
		recharge.setuId(sOrderNo);
		recharge.setsCustomerId(sCustomerId);
		recharge.setsOpenid(sOpenid);
		recharge.setsOrderNo(sOrderNo);
		recharge.setsSpbillCreateIp(whiteIP);
		recharge.setsBody(sBody);
		recharge.setmFund(mFund);
		recharge.setiTally(iTally);
		recharge.setsMemo(null);
		recharge.setsCreator(sCustomerId);
		recharge.setdCreateDate(now);
		recharge.setsModifieder(sCustomerId);
		recharge.setdModifiedDate(now);
		recharge.setiState(1);
		recharge.setiIndex(1);
		recharge.setiVersion(1);
		recharge.setsRecordKey(recharge.createRecordKey(recordKeyJam));
		
		MsgEmity me = rechargeDao.add(recharge);
		if (!me.isSuccess()) {
			return me;
		}
		
		return new MsgEmity(true, "创建充值成功！", recharge);
	}
	
	/**
	 * 查找订单
	 * @param sOrderNo
	 * @return
	 */
	@Override
	public MsgEmity findByOrder(String sOrderNo) {
		if (null == sOrderNo || "".equals(sOrderNo.trim())) {
			return MsgEmity.err(8001, "订单号缺失");
		}
		
		return rechargeDao.findByOrder(sOrderNo);
	}

	/**
	 * 修改订单
	 * @param iState
	 * @param sOrderNo 充值订单号
	 * @return
	 */
	@Override
	public MsgEmity changeState(int iState, String sOrderNo) {
		changeStateOld();//处理旧的数据
		
		if (iState == 3) {
			mapState.put(sOrderNo, iState);//已经支付成功则进行备份状态
		}
		
		MsgEmity me = rechargeDao.findByOrder(sOrderNo);
		if (!me.isSuccess()) {
			return me.appendDataCode(100);
		}
		
		Recharge recharge = me.getData();
		recharge.setiState(iState);
		recharge.setdModifiedDate(new Date());
		recharge.setiVersion(recharge.getiVersion() +1);
		recharge.setsRecordKey(recharge.createRecordKey(recordKeyJam));
		
		me = rechargeDao.changeState(recharge);
		if (!me.isSuccess()) {
			return me;
		}
		
		if (recharge.getiState().intValue() != iState && recharge.getiState().intValue() != 1) {
			mapState.remove(sOrderNo);//与要进行的操作一致
			return MsgEmity.err(7003, "指定订单的状态值已经改变,但与预定的状态不符");
		}
		
		mapState.remove(sOrderNo);//已经处理,则踢出
		
		rechargeService.changeCustomerAccount(recharge);//立即触发 '同步更新顾客账户中的余额与积分'
		
		return new MsgEmity(true, "更新状态成功！", recharge);
	}

	/**
	 * 修改旧的订单
	 */
	private void changeStateOld() {
		for (Map.Entry<String, Integer> entry : mapState.entrySet()) {
			MsgEmity me = rechargeDao.findByOrder(entry.getKey());
			if (!me.isSuccess() && (7001 != ((Integer)me.getData()).intValue() )) {
				continue;//查询异常
			}
			
			if (!me.isSuccess() && (7001 == ((Integer)me.getData()).intValue() )) {
				mapState.remove(entry.getKey());//数据不存在
				continue;
			}
			
			Recharge recharge = me.getData();
			recharge.setiState(entry.getValue());
			recharge.setdModifiedDate(new Date());
			recharge.setiVersion(recharge.getiVersion() +1);
			recharge.setsRecordKey(recharge.createRecordKey(recordKeyJam));
			
			me = rechargeDao.changeState(recharge);
			if (me.isSuccess()) {
				mapState.remove(entry.getKey());//已经处理,则踢出
				continue;
			}

			//--检查数据库--//
			me = rechargeDao.findState(entry.getKey());
			Integer iState = me.getData();
			if (null == iState || 7001 == ((Integer)me.getData()).intValue() ) {
				mapState.remove(entry.getKey());//没有这个订单
				continue;
			}
			
			if (iState.equals(entry.getValue())) {
				mapState.remove(entry.getKey());//与要进行的操作一致
				continue;
			}
		}
	}

	/**
	 * 新增微信退款记录
	 * @param wechatRefund
	 * @return
	 */
	@Override
	public MsgEmity addWechatRefund(WechatRefundBase wechatRefund) {
		return rechargeDao.addWechatRefund(wechatRefund);
	}
	
	/**
	 * 判断微信退款记录是否存在,存在返回非0
	 * @param sId
	 * @return
	 */
	@Override
	public MsgEmity hasWechatRefund(String sId) {
		return rechargeDao.hasWechatRefund(sId);
	}
	
}
